package com.ruoyi.zhgd.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.system.mapper.SysDeptMapper;
import com.ruoyi.zhgd.domain.*;
import com.ruoyi.zhgd.domain.bo.ZjNWarningSwlqBo;
import com.ruoyi.zhgd.domain.bo.ZjNWarningUserMessageBo;
import com.ruoyi.zhgd.domain.vo.*;
import com.ruoyi.zhgd.mapper.*;
import com.ruoyi.zhgd.service.INCementDataService;
import com.ruoyi.zhgd.service.IZjNWarningSwlqService;
import com.ruoyi.zhgd.service.IZjNWarningUsingService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.ruoyi.zhgd.domain.bo.NCementJwDataBo;
import com.ruoyi.zhgd.service.INCementJwDataService;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 水稳拌合站数据采集_2024-07-09_济微高速版Service业务层处理
 *
 * @author zyb
 * @date 2024-09-19
 */
@RequiredArgsConstructor
@Service
@DS("sjcj")
public class NCementJwDataServiceImpl implements INCementJwDataService {

    private final NCementJwDataMapper baseMapper;

    private final IZjNWarningSwlqService zjNWarningSwlqService;

    private final NCementDataMapper dataMapper;

    private final INCementDataService inCementDataService;
    private final ZjNCementMatchMapper cementMatchMapper;
    private final NWarningManagementMapper nWarningManagementMapper;
    private final ZjNWarningSwMapper warningSwMapper;
    private final SysDeptMapper sysDeptMapper;
    private final ZjNWarningUserMessageMapper zjNWarningUserMessageMapper;
    private final ZjNWarningUsingMapper zjNWarningUsingMapper;
    private final IZjNWarningUsingService iZjNWarningUsingService;


    /**
     * 查询水稳拌合站数据采集_2024-07-09_济微高速版
     */
    @Override
    public NCementJwDataVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询水稳拌合站数据采集_2024-07-09_济微高速版列表
     */
    @Override
    public TableDataInfo<NCementJwDataVo> queryPageList(NCementJwDataBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<NCementJwData> lqw = buildQueryWrapper(bo);
        Page<NCementJwDataVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询水稳拌合站数据采集_2024-07-09_济微高速版列表
     */
    @Override
    public List<NCementJwDataVo> queryList(NCementJwDataBo bo) {
        LambdaQueryWrapper<NCementJwData> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<NCementJwData> buildQueryWrapper(NCementJwDataBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<NCementJwData> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getSourceId() != null, NCementJwData::getSourceId, bo.getSourceId());
        lqw.eq(bo.getOccurTime() != null, NCementJwData::getOccurTime, bo.getOccurTime());
        lqw.eq(bo.getEndTime() != null, NCementJwData::getEndTime, bo.getEndTime());
        lqw.eq(StringUtils.isNotBlank(bo.getGlzl()), NCementJwData::getGlzl, bo.getGlzl());
        lqw.eq(StringUtils.isNotBlank(bo.getSjgl1()), NCementJwData::getSjgl1, bo.getSjgl1());
        lqw.eq(StringUtils.isNotBlank(bo.getSjgl2()), NCementJwData::getSjgl2, bo.getSjgl2());
        lqw.eq(StringUtils.isNotBlank(bo.getSjgl3()), NCementJwData::getSjgl3, bo.getSjgl3());
        lqw.eq(StringUtils.isNotBlank(bo.getSjgl4()), NCementJwData::getSjgl4, bo.getSjgl4());
        lqw.eq(StringUtils.isNotBlank(bo.getSjgl5()), NCementJwData::getSjgl5, bo.getSjgl5());
        lqw.eq(StringUtils.isNotBlank(bo.getSjgl6()), NCementJwData::getSjgl6, bo.getSjgl6());
        lqw.eq(StringUtils.isNotBlank(bo.getActualWater()), NCementJwData::getActualWater, bo.getActualWater());
        lqw.eq(StringUtils.isNotBlank(bo.getSjfl1()), NCementJwData::getSjfl1, bo.getSjfl1());
        lqw.eq(StringUtils.isNotBlank(bo.getSjfl2()), NCementJwData::getSjfl2, bo.getSjfl2());
        lqw.eq(StringUtils.isNotBlank(bo.getLlgl1()), NCementJwData::getLlgl1, bo.getLlgl1());
        lqw.eq(StringUtils.isNotBlank(bo.getLlgl2()), NCementJwData::getLlgl2, bo.getLlgl2());
        lqw.eq(StringUtils.isNotBlank(bo.getLlgl3()), NCementJwData::getLlgl3, bo.getLlgl3());
        lqw.eq(StringUtils.isNotBlank(bo.getLlgl4()), NCementJwData::getLlgl4, bo.getLlgl4());
        lqw.eq(StringUtils.isNotBlank(bo.getLlgl5()), NCementJwData::getLlgl5, bo.getLlgl5());
        lqw.eq(StringUtils.isNotBlank(bo.getLlgl6()), NCementJwData::getLlgl6, bo.getLlgl6());
        lqw.eq(StringUtils.isNotBlank(bo.getTheoreticalWater()), NCementJwData::getTheoreticalWater, bo.getTheoreticalWater());
        lqw.eq(StringUtils.isNotBlank(bo.getLlfl1()), NCementJwData::getLlfl1, bo.getLlfl1());
        lqw.eq(StringUtils.isNotBlank(bo.getLlfl2()), NCementJwData::getLlfl2, bo.getLlfl2());
        lqw.eq(bo.getCreateDate() != null, NCementJwData::getCreateDate, bo.getCreateDate());
        lqw.eq(StringUtils.isNotBlank(bo.getType()), NCementJwData::getType, bo.getType());
        lqw.eq(StringUtils.isNotBlank(bo.getRecipe()), NCementJwData::getRecipe, bo.getRecipe());
        return lqw;
    }

    /**
     * 新增水稳拌合站数据采集_2024-07-09_济微高速版
     */
    @Override
    public Boolean insertByBo(NCementJwDataBo bo) {
        NCementJwData add = BeanUtil.toBean(bo, NCementJwData.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改水稳拌合站数据采集_2024-07-09_济微高速版
     */
    @Override
    public Boolean updateByBo(NCementJwDataBo bo) {
        NCementJwData update = BeanUtil.toBean(bo, NCementJwData.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(NCementJwData entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除水稳拌合站数据采集_2024-07-09_济微高速版
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public Map<String, Object> homeData(NCementJwDataBo bo) {
        Map<String, Object> mapObject = new HashMap<>();

        List<Map<String,Object>> mapList1 =  baseMapper.homeData1(bo);
        if (CollectionUtils.isNotEmpty(mapList1)){
            //生产总量
            double sum = mapList1.stream().mapToDouble(map -> Double.parseDouble(String.valueOf(map.get("glzl")))).sum();
            String formattedSum = String.format("%.2f", sum);
            BigDecimal total = new BigDecimal(formattedSum).divide(BigDecimal.valueOf(1000),2,BigDecimal.ROUND_UP);
            //生产总批次
            int size = mapList1.size();
            //生产结束时间
            String endTime = String.valueOf(mapList1.get(0).get("end_time"));
            //预警总数
            ZjNWarningSwlqBo zjNWarningSwlqBo = new ZjNWarningSwlqBo();
            zjNWarningSwlqBo.setId(String.valueOf(bo.getId()));
            long warning = zjNWarningSwlqService.pageSw(zjNWarningSwlqBo, new PageQuery()).getTotal();

            //基本信息
            Map<String,Object> jibMap = new HashMap<>();
            jibMap.put("total",total);
            jibMap.put("size",size);
            jibMap.put("endTime",endTime);
            jibMap.put("warning",warning);

            mapObject.put("jib",jibMap);

            //水胶比
            List<Object> shuijb = mapList1.stream().map(t -> t.get("shuijb")).collect(Collectors.toList());
            List<Object> occur_time = mapList1.stream().map(t -> t.get("occur_time")).collect(Collectors.toList());
            List<String> shuijbName = new ArrayList<>();
            shuijbName.add("水胶比");
            Map<String, Object> shuijbMap = new HashMap<>();
            shuijbMap.put("shuijb", shuijb);
            shuijbMap.put("occur_time", occur_time);
            shuijbMap.put("shuijbName", shuijbName);
            mapObject.put("shuijb",shuijbMap);
//            List<Map<String, Object>> shuijbList = mapList1.stream()
//                .map(map -> {
//                    Map<String, Object> newMap = new HashMap<>();
//                    newMap.put("occur_time", map.get("occur_time"));
//                    newMap.put("shuijb", map.get("shuijb"));
//                    return newMap;
//                })
//                .collect(Collectors.toList());
//            mapObject.put("shuijb",shuijbList);

            //内掺比
            List<Object> neicbgl1 = mapList1.stream().map(t -> t.get("neicbgl1")).collect(Collectors.toList());
            List<Object> neicbgl2 = mapList1.stream().map(t -> t.get("neicbgl2")).collect(Collectors.toList());
            List<Object> neicbgl3 = mapList1.stream().map(t -> t.get("neicbgl3")).collect(Collectors.toList());
            List<Object> neicbgl4 = mapList1.stream().map(t -> t.get("neicbgl4")).collect(Collectors.toList());
            List<Object> neicbgl5 = mapList1.stream().map(t -> t.get("neicbgl5")).collect(Collectors.toList());
            List<Object> neicbgl6 = mapList1.stream().map(t -> t.get("neicbgl6")).collect(Collectors.toList());
            List<Object> neicbfl1 = mapList1.stream().map(t -> t.get("neicbfl1")).collect(Collectors.toList());
            List<Object> neicbfl2 = mapList1.stream().map(t -> t.get("neicbfl2")).collect(Collectors.toList());
            List<String> neicbName = new ArrayList<>();
            neicbName.add("骨料1");
            neicbName.add("骨料2");
            neicbName.add("骨料3");
            neicbName.add("骨料4");
            neicbName.add("骨料5");
            neicbName.add("骨料6");
            neicbName.add("粉料1");
            neicbName.add("粉料2");
            Map<String, Object> neicbMap = new HashMap<>();
            neicbMap.put("neicbgl1", neicbgl1);
            neicbMap.put("neicbgl2", neicbgl2);
            neicbMap.put("neicbgl3", neicbgl3);
            neicbMap.put("neicbgl4", neicbgl4);
            neicbMap.put("neicbgl5", neicbgl5);
            neicbMap.put("neicbgl6", neicbgl6);
            neicbMap.put("neicbfl1", neicbfl1);
            neicbMap.put("neicbfl2", neicbfl2);
            neicbMap.put("occur_time", occur_time);
            neicbMap.put("neicbName", neicbName);
            mapObject.put("neicb",neicbMap);

//            List<Map<String, Object>> neicbList = mapList1.stream()
//                .map(map -> {
//                    Map<String, Object> newMap = new HashMap<>();
//                    newMap.put("neicbgl1", map.get("neicbgl1"));
//                    newMap.put("neicbgl2", map.get("neicbgl2"));
//                    newMap.put("neicbgl3", map.get("neicbgl3"));
//                    newMap.put("neicbgl4", map.get("neicbgl4"));
//                    newMap.put("neicbgl5", map.get("neicbgl5"));
//                    newMap.put("neicbgl6", map.get("neicbgl6"));
//                    newMap.put("neicbfl1", map.get("neicbfl1"));
//                    newMap.put("neicbfl2", map.get("neicbfl2"));
//                    newMap.put("occur_time", map.get("occur_time"));
//                    return newMap;
//                })
//                .collect(Collectors.toList());
//            mapObject.put("neicb",neicbList);

            //生产流水
            List<Map<String, Object>> shengclsList = mapList1.stream()
                .map(map -> {
                    Map<String, Object> newMap = new HashMap<>();
                    newMap.put("occur_time", map.get("occur_time"));
                    newMap.put("glzl", map.get("glzl"));
                    newMap.put("sjgl1", map.get("sjgl1"));
                    newMap.put("sjgl2", map.get("sjgl2"));
                    newMap.put("sjgl3", map.get("sjgl3"));
                    newMap.put("sjgl4", map.get("sjgl4"));
                    newMap.put("sjgl5", map.get("sjgl5"));
                    newMap.put("sjgl6", map.get("sjgl6"));
                    newMap.put("sjfl1", map.get("sjfl1"));
                    newMap.put("sjfl2", map.get("sjfl2"));
                    newMap.put("actual_water", map.get("actual_water"));
                    newMap.put("shuijb", map.get("shuijb"));
                    return newMap;
                })
                .collect(Collectors.toList());
            mapObject.put("shengcls",shengclsList);
        }
        List<Map<String,Object>> mapList2 = baseMapper.homeData2(bo);
        if (CollectionUtils.isNotEmpty(mapList2)){
            //日流水统计
            List<Map<String, Object>> rilsList = mapList2.stream()
                .map(map -> {
                    Map<String, Object> newMap = new HashMap<>();
                    newMap.put("occur_time", map.get("occur_time"));
                    newMap.put("match_code", map.get("match_code"));
                    newMap.put("glzl", map.get("glzl"));
                    newMap.put("sjgl1", map.get("sjgl1"));
                    newMap.put("sjgl2", map.get("sjgl2"));
                    newMap.put("sjgl3", map.get("sjgl3"));
                    newMap.put("sjgl4", map.get("sjgl4"));
                    newMap.put("sjgl5", map.get("sjgl5"));
                    newMap.put("sjgl6", map.get("sjgl6"));
                    newMap.put("sjfl1", map.get("sjfl1"));
                    newMap.put("sjfl2", map.get("sjfl2"));
                    newMap.put("actual_water", map.get("actual_water"));
                    newMap.put("shuin", map.get("shuin"));
                    newMap.put("shil", map.get("shil"));
                    return newMap;
                })
                .collect(Collectors.toList());
            mapObject.put("rils",rilsList);

            //日流水总计
            String glzl = String.format("%.2f",rilsList.stream().mapToDouble(map -> Double.parseDouble(String.valueOf(ObjectUtils.isNotEmpty(map.get("glzl")) ? map.get("glzl") :0.0))).sum());
            String sjgl1 = String.format("%.2f",rilsList.stream().mapToDouble(map -> Double.parseDouble(String.valueOf(ObjectUtils.isNotEmpty(map.get("sjgl1")) ? map.get("sjgl1") :0.0))).sum());
            String sjgl2 = String.format("%.2f",rilsList.stream().mapToDouble(map -> Double.parseDouble(String.valueOf(ObjectUtils.isNotEmpty(map.get("sjgl2")) ? map.get("sjgl2") :0.0))).sum());
            String sjgl3 = String.format("%.2f",rilsList.stream().mapToDouble(map -> Double.parseDouble(String.valueOf(ObjectUtils.isNotEmpty(map.get("sjgl3")) ? map.get("sjgl3") :0.0))).sum());
            String sjgl4 = String.format("%.2f",rilsList.stream().mapToDouble(map -> Double.parseDouble(String.valueOf(ObjectUtils.isNotEmpty(map.get("sjgl4")) ? map.get("sjgl4") :0.0))).sum());
            String sjgl5 = String.format("%.2f",rilsList.stream().mapToDouble(map -> Double.parseDouble(String.valueOf(ObjectUtils.isNotEmpty(map.get("sjgl5")) ? map.get("sjgl5") :0.0))).sum());
            String sjgl6 = String.format("%.2f",rilsList.stream().mapToDouble(map -> Double.parseDouble(String.valueOf(ObjectUtils.isNotEmpty(map.get("sjgl6")) ? map.get("sjgl6") :0.0))).sum());
            String sjfl1 = String.format("%.2f",rilsList.stream().mapToDouble(map -> Double.parseDouble(String.valueOf(ObjectUtils.isNotEmpty(map.get("sjfl1")) ? map.get("sjfl1") :0.0))).sum());
            String sjfl2 = String.format("%.2f",rilsList.stream().mapToDouble(map -> Double.parseDouble(String.valueOf(ObjectUtils.isNotEmpty(map.get("sjfl6")) ? map.get("sjfl2") :0.0))).sum());
            String actual_water = String.format("%.2f",rilsList.stream().mapToDouble(map -> Double.parseDouble(String.valueOf(ObjectUtils.isNotEmpty(map.get("actual_water")) ? map.get("actual_water") :0.0))).sum());
            String shuin = String.format("%.2f",rilsList.stream().mapToDouble(map -> Double.parseDouble(String.valueOf(ObjectUtils.isNotEmpty(map.get("shuin")) ? map.get("shuin") :0.0))).sum());
            String shil = String.format("%.2f",rilsList.stream().mapToDouble(map -> Double.parseDouble(String.valueOf(ObjectUtils.isNotEmpty(map.get("shil")) ? map.get("shil") :0.0))).sum());
            Map<String,Object> rilsTotal = new HashMap<>();
            rilsTotal.put("glzl",glzl);
            rilsTotal.put("sjgl1",sjgl1);
            rilsTotal.put("sjgl2",sjgl2);
            rilsTotal.put("sjgl3",sjgl3);
            rilsTotal.put("sjgl4",sjgl4);
            rilsTotal.put("sjgl5",sjgl5);
            rilsTotal.put("sjgl6",sjgl6);
            rilsTotal.put("sjfl1",sjfl1);
            rilsTotal.put("sjfl2",sjfl2);
            rilsTotal.put("actual_water",actual_water);
            rilsTotal.put("shuin",shuin);
            rilsTotal.put("shil",shil);
            mapObject.put("rilsTotal",rilsTotal);

            //日产量统计
            List<Object> glzlDay = mapList2.stream().map(t -> new BigDecimal(String.valueOf(t.get("glzl"))).divide(BigDecimal.valueOf(1000),2,BigDecimal.ROUND_UP)).collect(Collectors.toList());
            List<Object> occur_time = mapList2.stream().map(t -> t.get("occur_time")).collect(Collectors.toList());
            List<String> riclName = new ArrayList<>();
            riclName.add("日产量");
            Map<String, Object> riclMap = new HashMap<>();
            riclMap.put("glzlDay", glzlDay);
            riclMap.put("occur_time", occur_time);
            riclMap.put("riclName", riclName);
            mapObject.put("ricl",riclMap);
//            List<Map<String, Object>> riclList = mapList2.stream()
//                .map(map -> {
//                    Map<String, Object> newMap = new HashMap<>();
//                    newMap.put("occur_time", map.get("occur_time"));
//                    newMap.put("glzl", map.get("glzl"));
//                    return newMap;
//                })
//                .collect(Collectors.toList());
//            mapObject.put("ricl",riclList);
        }
        return mapObject;
    }

    /**
     * 数据采集校验
     * @param id
     */
    @Override
    public void isQualified(String id) {
        // 判断添加配方名称配比设置信息
        CementJwDataVo vo = dataMapper.getById(id);
        if (ObjectUtils.isEmpty(vo)) {
            // 不预警
            System.err.println("没有查询到对应的水稳生产信息,不作预警.");
            return;
        } else {
            String deptId = vo.getDeptId();
            // 判断是否存在部门信息,没有则为合格
            if (ObjectUtils.isEmpty(deptId)) {
                // 不预警
                System.err.println("没有查询到对应的部门信息,不作预警.");
                return;
            } else {
                // 获取差值百分比
                CementJwDataVo cz = new CementJwDataVo();
                List<CementJwDataVo> list = new ArrayList<>();
                list.add(vo);
                List<CementJwDataVo> data = inCementDataService.handleList(list);
                for (CementJwDataVo datum : data) {
                    if (ObjectUtils.isNotEmpty(datum.getDesc()) && "差值百分比".equals(datum.getDesc())) {
                        cz = datum;
                    }
                }

                // 根据部门获取配比信息,有则预警,没有则不作预警判断
                LambdaQueryWrapper<ZjNCementMatch> lqw =  Wrappers.lambdaQuery();
                lqw.eq(ZjNCementMatch::getDeptId, deptId);
                lqw.eq(ZjNCementMatch::getStatus, "1");
                ZjNCementMatch match = cementMatchMapper.selectOne(lqw);
                if (ObjectUtils.isEmpty(match) || ObjectUtils.isEmpty(cz)) {
                    // 不预警
                    System.err.println("没有查询到对应的配比信息/差值信息,不作预警.");
                    return;
                } else {
                    // 差值对比,预警保存,短信发送
                    compare(match, cz);
                }
            }
        }
    }

    List<ZjNWarningSw> warnList = new ArrayList<>();

    @Transactional
    public void compare(ZjNCementMatch match, CementJwDataVo vo) {
        // 初始化预警消息
        warnList = new ArrayList<>();
        // 骨料1
        if (ObjectUtils.isNotEmpty(match.getGravel1Min()) && ObjectUtils.isNotEmpty(match.getGravel1Max()) && ObjectUtils.isNotEmpty(vo.getSjgl1())) {
            BigDecimal gravelMin = match.getGravel1Min();
            BigDecimal gravelMax = match.getGravel1Max();
            BigDecimal gravelAct = vo.getSjgl1();
            if (!(gravelAct.compareTo(gravelMin) >= 0 && gravelAct.compareTo(gravelMax) <= 0)) {
                // 骨料1 预警
                BigDecimal abs;
                if (gravelAct.compareTo(BigDecimal.ZERO) < 0) { // 负的
                    // 取绝对值
                    abs = gravelAct.subtract(gravelMin).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                    // 对比初中高
                }
                else { // 正的
                    // 取绝对值
                    abs = gravelAct.subtract(gravelMax).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                    // 对比初中高
                }
                int level = getLevel(abs, vo.getDeptId());
                // 保存预警信息
                ZjNWarningSw entity = saveWarnInfo(vo, level, "骨料1", abs.toString());
                warnList.add(entity);
            }
        }
        // 骨料2
        if (ObjectUtils.isNotEmpty(match.getGravel2Min()) && ObjectUtils.isNotEmpty(match.getGravel2Max()) && ObjectUtils.isNotEmpty(vo.getSjgl2())) {
            BigDecimal gravelMin = match.getGravel2Min();
            BigDecimal gravelMax = match.getGravel2Max();
            BigDecimal gravelAct = vo.getSjgl2();
            if (!(gravelAct.compareTo(gravelMin) >= 0 && gravelAct.compareTo(gravelMax) <= 0)) {
                // 骨料2 预警
                BigDecimal abs;
                if (gravelAct.compareTo(BigDecimal.ZERO) < 0) { // 负的
                    abs = gravelAct.subtract(gravelMin).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                else { // 正的
                    abs = gravelAct.subtract(gravelMax).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                int level = getLevel(abs, vo.getDeptId());
                // 保存预警信息
                ZjNWarningSw entity = saveWarnInfo(vo, level, "骨料2", abs.toString());
                warnList.add(entity);
            }
        }
        // 骨料3
        if (ObjectUtils.isNotEmpty(match.getGravel3Min()) && ObjectUtils.isNotEmpty(match.getGravel3Max()) && ObjectUtils.isNotEmpty(vo.getSjgl3())) {
            BigDecimal gravelMin = match.getGravel3Min();
            BigDecimal gravelMax = match.getGravel3Max();
            BigDecimal gravelAct = vo.getSjgl3();
            if (!(gravelAct.compareTo(gravelMin) >= 0 && gravelAct.compareTo(gravelMax) <= 0)) {
                // 骨料3 预警
                BigDecimal abs;
                if (gravelAct.compareTo(BigDecimal.ZERO) < 0) { // 负的
                    abs = gravelAct.subtract(gravelMin).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                else { // 正的
                    abs = gravelAct.subtract(gravelMax).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                int level = getLevel(abs, vo.getDeptId());
                // 保存预警信息
                ZjNWarningSw entity = saveWarnInfo(vo, level, "骨料3", abs.toString());
                warnList.add(entity);
            }
        }
        // 骨料4
        if (ObjectUtils.isNotEmpty(match.getGravel4Min()) && ObjectUtils.isNotEmpty(match.getGravel4Max()) && ObjectUtils.isNotEmpty(vo.getSjgl4())) {
            BigDecimal gravelMin = match.getGravel4Min();
            BigDecimal gravelMax = match.getGravel4Max();
            BigDecimal gravelAct = vo.getSjgl4();
            if (!(gravelAct.compareTo(gravelMin) >= 0 && gravelAct.compareTo(gravelMax) <= 0)) {
                // 骨料4 预警
                BigDecimal abs;
                if (gravelAct.compareTo(BigDecimal.ZERO) < 0) { // 负的
                    abs = gravelAct.subtract(gravelMin).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                else { // 正的
                    abs = gravelAct.subtract(gravelMax).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                int level = getLevel(abs, vo.getDeptId());
                // 保存预警信息
                ZjNWarningSw entity = saveWarnInfo(vo, level, "骨料4", abs.toString());
                warnList.add(entity);
            }
        }
        // 骨料5
        if (ObjectUtils.isNotEmpty(match.getGravel5Min()) && ObjectUtils.isNotEmpty(match.getGravel5Max()) && ObjectUtils.isNotEmpty(vo.getSjgl5())) {
            BigDecimal gravelMin = match.getGravel5Min();
            BigDecimal gravelMax = match.getGravel5Max();
            BigDecimal gravelAct = vo.getSjgl5();
            if (!(gravelAct.compareTo(gravelMin) >= 0 && gravelAct.compareTo(gravelMax) <= 0)) {
                // 骨料5 预警
                BigDecimal abs;
                if (gravelAct.compareTo(BigDecimal.ZERO) < 0) { // 负的
                    abs = gravelAct.subtract(gravelMin).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                else { // 正的
                    abs = gravelAct.subtract(gravelMax).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                int level = getLevel(abs, vo.getDeptId());
                // 保存预警信息
                ZjNWarningSw entity = saveWarnInfo(vo, level, "骨料5", abs.toString());
                warnList.add(entity);
            }
        }
        // 骨料6
        if (ObjectUtils.isNotEmpty(match.getGravel6Min()) && ObjectUtils.isNotEmpty(match.getGravel6Max()) && ObjectUtils.isNotEmpty(vo.getSjgl6())) {
            BigDecimal gravelMin = match.getGravel6Min();
            BigDecimal gravelMax = match.getGravel6Max();
            BigDecimal gravelAct = vo.getSjgl6();
            if (!(gravelAct.compareTo(gravelMin) >= 0 && gravelAct.compareTo(gravelMax) <= 0)) {
                // 骨料6 预警
                BigDecimal abs;
                if (gravelAct.compareTo(BigDecimal.ZERO) < 0) { // 负的
                    abs = gravelAct.subtract(gravelMin).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                else { // 正的
                    abs = gravelAct.subtract(gravelMax).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                int level = getLevel(abs, vo.getDeptId());
                // 保存预警信息
                ZjNWarningSw entity = saveWarnInfo(vo, level, "骨料6", abs.toString());
                warnList.add(entity);
            }
        }
        // 粉料1
        if (ObjectUtils.isNotEmpty(match.getPowder1Min()) && ObjectUtils.isNotEmpty(match.getPowder1Max()) && ObjectUtils.isNotEmpty(vo.getSjfl1())) {
            BigDecimal gravelMin = match.getPowder1Min();
            BigDecimal gravelMax = match.getPowder1Max();
            BigDecimal gravelAct = vo.getSjfl1();
            if (!(gravelAct.compareTo(gravelMin) >= 0 && gravelAct.compareTo(gravelMax) <= 0)) {
                // 粉料1 预警
                BigDecimal abs;
                if (gravelAct.compareTo(BigDecimal.ZERO) < 0) { // 负的
                    abs = gravelAct.subtract(gravelMin).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                else { // 正的
                    abs = gravelAct.subtract(gravelMax).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                int level = getLevel(abs, vo.getDeptId());
                // 保存预警信息
                ZjNWarningSw entity = saveWarnInfo(vo, level, "粉料1", abs.toString());
                warnList.add(entity);
            }
        }
        // 粉料2
        if (ObjectUtils.isNotEmpty(match.getPowder2Min()) && ObjectUtils.isNotEmpty(match.getPowder2Max()) && ObjectUtils.isNotEmpty(vo.getSjfl2())) {
            BigDecimal gravelMin = match.getPowder2Min();
            BigDecimal gravelMax = match.getPowder2Max();
            BigDecimal gravelAct = vo.getSjfl2();
            if (!(gravelAct.compareTo(gravelMin) >= 0 && gravelAct.compareTo(gravelMax) <= 0)) {
                // 粉料2 预警
                BigDecimal abs;
                if (gravelAct.compareTo(BigDecimal.ZERO) < 0) { // 负的
                    abs = gravelAct.subtract(gravelMin).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                else { // 正的
                    abs = gravelAct.subtract(gravelMax).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                int level = getLevel(abs, vo.getDeptId());
                // 保存预警信息
                ZjNWarningSw entity = saveWarnInfo(vo, level, "粉料2", abs.toString());
                warnList.add(entity);
            }
        }
        // 水
        if (ObjectUtils.isNotEmpty(match.getWaterMin()) && ObjectUtils.isNotEmpty(match.getWaterMax()) && ObjectUtils.isNotEmpty(vo.getActualWater())) {
            BigDecimal gravelMin = match.getWaterMin();
            BigDecimal gravelMax = match.getWaterMax();
            BigDecimal gravelAct = vo.getActualWater();
            if (!(gravelAct.compareTo(gravelMin) >= 0 && gravelAct.compareTo(gravelMax) <= 0)) {
                // 水 预警
                BigDecimal abs;
                if (gravelAct.compareTo(BigDecimal.ZERO) < 0) { // 负的
                    abs = gravelAct.subtract(gravelMin).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                else { // 正的
                    abs = gravelAct.subtract(gravelMax).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                int level = getLevel(abs, vo.getDeptId());
                // 保存预警信息
                ZjNWarningSw entity = saveWarnInfo(vo, level, "水", abs.toString());
                warnList.add(entity);
            }
        }
        // 水胶比
        if (ObjectUtils.isNotEmpty(match.getSjbMin()) && ObjectUtils.isNotEmpty(match.getSjbMax()) && ObjectUtils.isNotEmpty(vo.getSjbR())) {
            BigDecimal gravelMin = match.getSjbMin();
            BigDecimal gravelMax = match.getSjbMax();
            BigDecimal gravelAct = vo.getSjbR();
            if (!(gravelAct.compareTo(gravelMin) >= 0 && gravelAct.compareTo(gravelMax) <= 0)) {
                // 水胶比 预警
                BigDecimal abs;
                if (gravelAct.compareTo(BigDecimal.ZERO) < 0) { // 负的
                    abs = gravelAct.subtract(gravelMin).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                else { // 正的
                    abs = gravelAct.subtract(gravelMax).abs().setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                int level = getLevel(abs, vo.getDeptId());
                // 保存预警信息
                ZjNWarningSw entity = saveWarnInfo(vo, level, "水胶比", abs.toString());
                warnList.add(entity);
            }
        }
        // 发送短信通知
        send(vo.getDeptId(), vo, warnList, 1);
    }

    /**
     * 手动校验
     * @param bo
     */
    @Override
    public void handCheck(NCementJwDataBo bo) {
        if (org.apache.commons.lang3.ObjectUtils.isEmpty(bo.getIds())) {
            throw new ServiceException("ID列表不能为空");
        }
        List<String> ids = bo.getIds();
        // 去重
        ids = new ArrayList<>(new HashSet<>(ids));
        for (String id : ids) {
            // 调用判断方法
            isQualified(id);
        }
    }

    BigDecimal extra = BigDecimal.ZERO;
    /**
     * 获取初中高预警等级
     * @param data
     * @param deptId
     * @return
     */
    public int getLevel(BigDecimal data, String deptId) {
        int level = 0;
        // 获取水稳对应部门的初中高预警等级范围
        LambdaQueryWrapper<NWarningManagement> lqw = new LambdaQueryWrapper<>();
        lqw.eq(NWarningManagement::getTypeId, "2");
        lqw.eq(NWarningManagement::getDeptId, deptId);
        NWarningManagement entity = nWarningManagementMapper.selectOne(lqw);
        if (ObjectUtils.isEmpty(entity)) {
            return 0;
        }
//        extra = BigDecimal.ZERO;
        // 初级下限
        if (ObjectUtils.isNotEmpty(entity.getDownLowWarning()) && data.compareTo(entity.getDownLowWarning()) < 0) {
            level = 0;
//            extra = data.subtract(entity.getDownLowWarning());
        }
        // 初级上限
        else if (ObjectUtils.isNotEmpty(entity.getUpLowWarning()) && data.compareTo(entity.getUpLowWarning()) <= 0) {
            level = 1;
//            extra = data.subtract(entity.getUpLowWarning());
        }
        // 中级下限
        else if (ObjectUtils.isNotEmpty(entity.getDownMiddleWarning()) && data.compareTo(entity.getDownMiddleWarning()) < 0) {
            level = 1;
//            extra = data.subtract(entity.getDownMiddleWarning());
        }
        // 中级上限
        else if (ObjectUtils.isNotEmpty(entity.getUpMiddleWarning()) && data.compareTo(entity.getUpMiddleWarning()) <= 0) {
            level = 2;
//            extra = data.subtract(entity.getUpMiddleWarning());
        }
        // 高级下限
        else if (ObjectUtils.isNotEmpty(entity.getDownAdvancedWarning()) && data.compareTo(entity.getDownAdvancedWarning()) < 0) {
            level = 2;
//            extra = data.subtract(entity.getDownAdvancedWarning());
        }
        // 高级上限
        else if (ObjectUtils.isNotEmpty(entity.getUpAdvancedWarning()) && data.compareTo(entity.getUpAdvancedWarning()) <= 0) {
            level = 3;
//            extra = data.subtract(entity.getUpAdvancedWarning());
        }
        else {
            level = 4;
        }
        return level;
    }

    /**
     * 保存预警信息
     * @param vo
     * @param level
     * @param warnItem
     * @param outRange
     */
    @Transactional
    public ZjNWarningSw saveWarnInfo(CementJwDataVo vo, int level, String warnItem, String outRange) {
        String gd = "";
        if (level == 1) {
            gd = "初级";
        } else if (level == 2) {
            gd = "中级";
        } else if (level == 3) {
            gd = "高级";
        }
        ZjNWarningSw entity = new ZjNWarningSw();
        entity.setGrade(String.valueOf(level));
        entity.setInsterTime(new Date());
        entity.setRemark(warnItem+"产生了" + gd + "预警");
        entity.setBusinessId(vo.getId());
        entity.setDisposalStatus(1);
        entity.setStationCode(vo.getType());
        entity.setDeptCode(vo.getDeptId());
        entity.setBuzTime(vo.getOccurTime());
        entity.setMatchName(vo.getStationName());
        entity.setWarnItem(warnItem);
        entity.setOutRange(outRange);
        entity.setDelFlag("0");

        switch (warnItem) {
            case "骨料1":
                entity.setCz(vo.getSjgl1().toString());
                break;
            case "骨料2":
                entity.setCz(vo.getSjgl2().toString());
                break;
            case "骨料3":
                entity.setCz(vo.getSjgl3().toString());
                break;
            case "骨料4":
                entity.setCz(vo.getSjgl4().toString());
                break;
            case "骨料5":
                entity.setCz(vo.getSjgl5().toString());
                break;
            case "骨料6":
                entity.setCz(vo.getSjgl6().toString());
                break;
            case "粉料1":
                entity.setCz(vo.getSjfl1().toString());
                break;
            case "粉料2":
                entity.setCz(vo.getSjfl2().toString());
                break;
            case "水":
                entity.setCz(vo.getActualWater().toString());
                break;
            case "水胶比":
                entity.setCz(vo.getSjbR().toString());
                break;
        }

        warningSwMapper.insert(entity);
        return entity;
    }

    @Transactional
    private void send(String deptId, CementJwDataVo vo, List<ZjNWarningSw> warnList, int isSend) {
        if (isSend != 1) {
            System.err.println("不发送水稳预警信息...");
            return;
        }
        String message = "";
        String deptName = ObjectUtils.isNotEmpty(vo.getDeptName()) ? vo.getDeptName() + "-" : "[标段]-";
        message = message + deptName;
        String matchName = "";
        String buzTime = "";
        String forMsg = "";
        // 短信内容编辑
        for (ZjNWarningSw entity : warnList) {
            // 拌合站名称
            matchName = entity.getMatchName();
            // 业务数据时间
            buzTime = entity.getBuzTime();
            // 预警项目
            String warnItem = entity.getWarnItem();
            // 误差
            String cz = entity.getCz();
            // 超出比例
            String outRange = entity.getOutRange();
            // 预警级别
            String grade = entity.getGrade();
            String level = "";
            if (StringUtils.isNotEmpty(grade)) {
                if ("1".equals(grade)) {
                    level = "初级预警";
                }
                else if ("2".equals(grade)) {
                    level = "中级预警";
                }
                else if ("3".equals(grade)) {
                    level = "高级预警";
                }
                else {
                    level = "预警";
                }
            } else {
                level = "预警";
            }
            // 编辑消息
            forMsg = forMsg + warnItem + "误差" + cz + "%" + "超出上下限" + outRange + "%产生了" + level + ";";
        }
        message = message + matchName;
        message = message + "("+buzTime+")的";
        message = message + forMsg;
        System.err.println("预警消息:" + message);

        // 根据deptId获取祖级列表
        SysDept dept = sysDeptMapper.getById(Long.valueOf(deptId));
        String ancestors = ObjectUtils.isNotEmpty(dept) ? dept.getAncestors() : null;
        String[] ids = ObjectUtils.isNotEmpty(ancestors) ? ancestors.split(",") : new String[]{} ;
        // 根据部门id获取预警标识
        ZjNWarningUsing entity = zjNWarningUsingMapper.getByDeptId(deptId, ids);
        Long open = ObjectUtils.isNotEmpty(entity) ? entity.getUsingMsgSw() : 0;
        if (open != 1) {
            System.err.println("水稳短信通知已关闭...");
            return;
        }
        // 发送人获取:
        ZjNWarningUserMessageBo bo = new ZjNWarningUserMessageBo();
        bo.setId(deptId);
        QueryWrapper<ZjNWarningUserMessage> wrapper1 = new QueryWrapper<>();
        wrapper1.eq("a.del_flag", "0");
        wrapper1.eq("u.del_flag", "0");
        wrapper1.like("a.warn_val_sw", "1");
        List<ZjNWarningUserMessageVo> list = zjNWarningUserMessageMapper.getZlyjList(wrapper1, bo);
        List<String> phonenumber = list.stream().map(ZjNWarningUserMessageVo::getPhonenumber).collect(Collectors.toList());
        // 发送短信
        try {
            // 推送失败 返1 成功 返0
            int send = iZjNWarningUsingService.send(phonenumber, message);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("短信发送失败");
        }
    }

}
